﻿using System;
using System.ServiceModel;
using System.Threading;
using System.Windows;
using System.Windows.Input;

namespace FastNet.Examples.ChatClient.Windows
{
	public partial class MainWindow : Window
	{
		public sealed class Commands : FastCommands
		{
			public const Int32 UserConnected	= 101;
			public const Int32 UserDisconnected = 102;
			public const Int32 UserMessage		= 103;
		}


		public MainWindow()
		{
			InitializeComponent();

			this.Loaded += new RoutedEventHandler( MainWindow_Loaded );
		}


		private void MainWindow_Loaded( Object sender, RoutedEventArgs e )
		{
			m_client = FastClient.Create( new NetTcpBinding(), new EndpointAddress( "net.tcp://127.0.0.1:1666/ChatServer" ), SynchronizationContext.Current );

			// Processing events          
			m_client.Disconnected			+= OnDisconnected;
			m_client.ProcessMessage			+= OnProcessMessage;

			this.InputLog.AppendText( "* connecting" );
			CommandManager.InvalidateRequerySuggested();

			this.InputLog.AppendText( Environment.NewLine + "* connected" );

			try
			{
				m_client.Open( Guid.NewGuid().ToString(), null ).Wait();

				m_connected = true;

			}
			catch ( EndpointNotFoundException )
			{
				// The server is not found
				MessageBox.Show( "The server doesn't exist" );
				this.Close();
			}
			catch ( FaultException ex )
			{
				// The logon has failed
				MessageBox.Show( ex.Message );
				this.Close();
			}
		}


		private void OnDisconnected( Object sender, EventArgs e )
		{
			m_connected = false;

			CommandManager.InvalidateRequerySuggested();

			this.InputLog.AppendText( Environment.NewLine + "* disconnected" );

			// We can reconnect here like this:
			// m_client.Reset();
			// m_client.Open( "Your", "Credentials" );
		}


		private void OnProcessMessage( Object sender, MessageEventArgs e )
		{
			if ( e.Message.Command == Commands.UserMessage )
			{
				String		msg		= e.Message.Get<String>( "Message" );
				String		user	= e.Message.Get<String>( "Nickname" );
				DateTime	time	= e.Message.Get<DateTime>( "Time" );

				this.InputLog.AppendText( Environment.NewLine );
				this.InputLog.AppendText( String.Format( "[{0}] {1}: {2}", time, user, msg ) );
			}
		}


		protected override void OnClosed( EventArgs e )
		{
			m_client.Close();
			
			base.OnClosed( e );
		}


		private void OnSendCanExecute( Object sender, CanExecuteRoutedEventArgs e )
		{
			e.CanExecute = m_connected;
		}


		private void OnSendExecuted( Object sender, ExecutedRoutedEventArgs e )
		{
			m_client.Send( new FastMessage( Commands.UserMessage ).Add( "Message", this.InputMessage.Text ) );

			this.InputMessage.Text = String.Empty;
			this.InputMessage.Focus();
		}


		private Boolean		m_connected;
		private FastClient	m_client;
	}
}
